package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.type.TypeReference;
import com.heima.common.constants.message.WmNewsUpDownConstants;
import com.heima.common.dtos.PageResult;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.threadlocal.UserThreadLocalUtils;
import com.heima.common.util.BeanHelper;
import com.heima.common.util.JsonUtils;
import com.heima.model.media.dtos.WmNewsDto;
import com.heima.model.media.dtos.WmNewsPageReqDto;
import com.heima.model.media.dtos.WmNewsResultDTO;
import com.heima.wemedia.entity.WmMaterial;
import com.heima.wemedia.entity.WmNews;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.service.WmMaterialService;
import com.heima.wemedia.service.WmNewsAuditService;
import com.heima.wemedia.service.WmNewsMaterialService;
import com.heima.wemedia.service.WmNewsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

import static com.heima.common.constants.message.WmNewsUpDownConstants.WM_NEWS_UP_OR_DOWN_TOPIC;

/**
 * <p>
 * 自媒体图文内容信息表 服务实现类
 * </p>
 *
 * @author HM
 * @since 2021-11-24
 */
@Slf4j
@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    /**
     * 分页查询
     * @param dto
     * @return
     */
    @Override
    public PageResult<WmNewsResultDTO> findByPage(WmNewsPageReqDto dto) {
//        获取用户id
        Integer userId = UserThreadLocalUtils.getUserId();
        if(userId==null || userId==0){
            throw new LeadException(AppHttpCodeEnum.NEED_LOGIN);
        }
//        设置分页
        IPage<WmNews> iPage = new Page<>(dto.getPage(),dto.getSize());
//        设置查询
        QueryWrapper<WmNews> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(WmNews::getWmUserId,userId);
        if(dto.getStatus() != null && dto.getStatus() != -1){
            if(dto.getStatus()==1){
//                 where status in (1,3)
                queryWrapper.lambda().in(WmNews::getStatus,new Integer[]{1,3});
            }
            else if(dto.getStatus()==4){
                queryWrapper.lambda().in(WmNews::getStatus,new Integer[]{4,8,9});
            }
            else {
                queryWrapper.lambda().eq(WmNews::getStatus, dto.getStatus());
            }
        }
        if(dto.getChannelId() != null){
            queryWrapper.lambda().eq(WmNews::getChannelId,dto.getChannelId());
        }
        if(StringUtils.isNotBlank(dto.getKeyword())){
            queryWrapper.lambda().like(WmNews::getTitle,dto.getKeyword());
        }
        if(dto.getBeginPubDate() != null){
            queryWrapper.lambda().ge(WmNews::getPublishTime,dto.getBeginPubDate());
        }
        if(dto.getEndPubDate() != null){
            queryWrapper.lambda().le(WmNews::getPublishTime,dto.getEndPubDate());
        }
//        分页
        IPage<WmNews> wmNewsIPage = page(iPage, queryWrapper);
        if(wmNewsIPage == null || CollectionUtils.isEmpty(wmNewsIPage.getRecords())){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
//        构造对象
        return new PageResult<>(
                dto.getPage(),
                dto.getSize(),
                wmNewsIPage.getTotal(),
                BeanHelper.copyWithCollection(wmNewsIPage.getRecords(),WmNewsResultDTO.class));
    }

    @Autowired
    private WmNewsMaterialService newsMaterialService;
    @Autowired
    private WmNewsAuditService wmNewsAuditService;
    /**
     * 文章新增修改提交
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public void submit(WmNewsDto dto) {
        Integer userId = UserThreadLocalUtils.getUserId();
        if(userId==null || userId==0){
            throw new LeadException(AppHttpCodeEnum.NEED_LOGIN);
        }
        WmNews wmNews = BeanHelper.copyProperties(dto, WmNews.class);
//        设置新增的数据
        if(dto.getId()==null){
            wmNews.setWmUserId(userId);
            wmNews.setCreatedTime(new Date());
            wmNews.setEnable(true);
        }
//        处理封面图片
        List<String> images = dto.getImages();
        if(!CollectionUtils.isEmpty(images)){
//            StringBuilder sbr = new StringBuilder();
//            for (String image : images) {
//                if(sbr.length()>0){
//                    sbr.append(",");
//                }
//                sbr.append(image);
//            }
//            String imageStr = sbr.toString();
            String imageStr = images.stream().collect(Collectors.joining(","));
            wmNews.setImages(imageStr);
        }
//        根据状态设置提交时间
        if(dto.getStatus()==0){
            wmNews.setSubmitedTime(null);
        }else{
            wmNews.setSubmitedTime(new Date());
        }
//        保存或修改 文章
        saveOrUpdate(wmNews);
//        获取自媒体文章id
        Integer wmNewsId = wmNews.getId();
//        如果是修改，删除中间表数据
        if(dto.getId() != null){
            newsMaterialService.removeByNewsId(wmNewsId);
        }
//        处理内容中的素材id
        List<Integer> contentImageIds = handlerContentImage(dto.getContent());
//        保存文章素材中间表数据
        newsMaterialService.saveBatchByNewsIdAndImageIds(wmNewsId,contentImageIds,0);

//        处理封面的素材id
        if(!CollectionUtils.isEmpty(dto.getImages())){
//            有封面才需要处理
            List<Integer> imageIds = handlerImage(dto.getImages());
//        保存文章素材中间表数据
            newsMaterialService.saveBatchByNewsIdAndImageIds(wmNewsId,imageIds,1);
        }
//        如果是提交审核状态，就需要去进行文章的审核
        if(dto.getStatus() == 1){
            log.info("开始，自动审核文章");
            wmNewsAuditService.auditNews(wmNews);
        }

    }

    @Autowired
    private KafkaTemplate kafkaTemplate;
    @Override
    public void downOrUp(WmNewsDto dto) {
        Integer userId = UserThreadLocalUtils.getUserId();
        if(userId==null || userId==0){
            throw new LeadException(AppHttpCodeEnum.NEED_LOGIN);
        }
        Integer wmNewsId = dto.getId();
        Boolean enable = dto.getEnable();

        WmNews wmNews = getById(wmNewsId);
        if(wmNews == null){
            log.error("文章不存在");
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        if(wmNews.getStatus() !=9 ){
            log.error("文章不是已发布状态，不能上下架");
            throw new LeadException(AppHttpCodeEnum.PARAM_INVALID);
        }
        Long articleId = wmNews.getArticleId();

        wmNews = new WmNews();
        wmNews.setId(wmNewsId);
        wmNews.setEnable(enable);
        boolean b = updateById(wmNews);
//        发送卡夫卡消息 消息内容，articleId，enable  0-上架  1-下架
        Map<String,Long> map = new HashMap<>();
        map.put("articleId",articleId);
        map.put("enable",enable?0L:1L);
        String msg = JsonUtils.toString(map);
        log.info("上下架发送kafka消息，msg={}",msg);
        kafkaTemplate.send(WM_NEWS_UP_OR_DOWN_TOPIC,msg);
    }

    @Autowired
    private WmMaterialService wmMaterialService;
    /**
     * 处理封面图片
     * @param images
     * @return
     */
    private List<Integer> handlerImage(List<String> images) {
//        select * from wm_material where url
        QueryWrapper<WmMaterial> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(WmMaterial::getUrl,images);
        List<WmMaterial> list = wmMaterialService.list(queryWrapper);
        List<Integer> ids = list.stream().map(WmMaterial::getId).collect(Collectors.toList());
        return ids;
    }

    /**
     * 处理content中的图片获取素材id
     * @param content
     * @return
     */
    private List<Integer> handlerContentImage(String content) {

        List<Integer> ids = new ArrayList<>();
//        List<HashMap> list = JsonUtils.toList(content, HashMap.class);
        List<Map<String,Object>> list = JsonUtils.nativeRead(content, new TypeReference<List<Map<String, Object>>>() {});
        for (Map<String, Object> map : list) {
            if("image".equals(map.get("type").toString())){
                Integer materialId = Integer.valueOf(map.get("id").toString());
                ids.add(materialId);
            }
        }
        return ids;
    }
}
